package com.zhz.mutil.infras.utils;

import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.zhz.mutil.domain.contract.constants.DbDataSourceConstant;
import com.zhz.mutil.domain.contract.dto.DbDataSourceDTO;
import com.zhz.mutil.infras.exception.ServiceException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Set;

/**
 * 操作数据源工具类
 *
 * @author zhouhengzhe
 */
@Component
public class DbOprUtil {

    @Autowired
    private DataSource dataSource;
    @Resource
    private DefaultDataSourceCreator dataSourceCreator;


    /**
     * 添加数据源
     */
    public Set<String> addDataSource(DbDataSourceDTO sourceDTO) {
        // 根据数据库类型设置驱动名称
        switch (sourceDTO.getType().toLowerCase()) {
            case "mysql":
                sourceDTO.setDriverClassName(DbDataSourceConstant.MYSQL_HIGH_DRIVER_CLASS_NAME);
                break;
            case "oracle":
                sourceDTO.setDriverClassName(DbDataSourceConstant.ORACLE_DRIVER_CLASS_NAME);
                break;
            case "postgresql":
                sourceDTO.setDriverClassName(DbDataSourceConstant.POSTGRESQL_HIGH_DRIVER_CLASS_NAME);
                break;
            default:
                return null;
        }
        boolean status = DbLinkUtil.verifyUrlConnStatus(sourceDTO.getUrl(), sourceDTO.getDriverClassName(), sourceDTO.getUsername(), sourceDTO.getPassword());
        if (!status) {
            throw new ServiceException("数据源链接失败！，当前要切换的数据源为：" + sourceDTO.getPoolName());
        }
        DataSourceProperty dataSourceProperty = new DataSourceProperty();
        BeanUtils.copyProperties(sourceDTO, dataSourceProperty);
        //这里可以自己把动态数据源的配置放进去
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        DataSource dataSource = dataSourceCreator.createDataSource(dataSourceProperty);
        // 添加数据源
        ds.addDataSource(sourceDTO.getPoolName(), dataSource);
        return ds.getDataSources().keySet();
    }

    /**
     * 获取所有数据源
     *
     * @return Set<String>
     */
    public Set<String> getAllDataSource() {
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        return ds.getDataSources().keySet();
    }

    /**
     * 获取所有数据源，返回
     *
     * @return DynamicRoutingDataSource
     */
    public DynamicRoutingDataSource getDataSource() {
        return (DynamicRoutingDataSource) dataSource;
    }

    /**
     * 根据数据源名称删除数据源
     */
    public void removeByDataSourceByName(String dataSourceName) {
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        ds.removeDataSource(dataSourceName);
    }

    /**
     * 手动切换到该数据源
     */
    public void changeByDataSourceByName(String dataSourceName) {
        Set<String> set = getAllDataSource();
        if (set != null && !set.isEmpty() && set.contains(dataSourceName)) {
            DynamicDataSourceContextHolder.push(dataSourceName);
        } else {
            throw new ServiceException("数据源链接切换失败！,当前要切换的数据源为：" + dataSourceName);
        }
    }


}